import DebugExt from "../base/DebugExt";
import { Util } from "../base/Util";
import CanvasExt from "../ccExt/CanvasExt";

const { ccclass, property, disallowMultiple } = cc._decorator;

/**
 * 等比缩放节点基类，不提供实际功能
 */
@ccclass
@disallowMultiple
export default class UniformScaleBase extends cc.Component {

    // delay update function
    protected throttledUpdateLayout;
    // 节点原始缩放
    protected originalScale: number = 1;

    protected onLoad(): void {
        this.originalScale = this.node.scale;
        this.throttledUpdateLayout = Util.throttle(this.doUniformScale.bind(this));
        // 监听canvas尺寸变化
        CanvasExt.on(cc.Node.EventType.SIZE_CHANGED, this.throttledUpdateLayout, this);
    }

    protected onDestroy(): void {
        CanvasExt.off(cc.Node.EventType.SIZE_CHANGED, this.throttledUpdateLayout, this);
    }

    protected start(): void {
        this.throttledUpdateLayout();
    }

    protected onEnable(): void {
        this.throttledUpdateLayout();
    }

    protected doUniformScale() {
        throw new Error("具体功能由子类型实现！");
    }

    /**
     * 当前节点是否激活
     */
    protected get active(): boolean {
        return !!this && this.isValid && !!this.node && this.node.activeInHierarchy;
    }

    /**
     * 返回视图窗口可见区域尺寸
     */
    protected get viewSize(): cc.Size {
        return cc.view.getVisibleSize();
    }

    /**
     * 返回视图的设计分辨率
     */
    protected get designSize(): cc.Size {
        return cc.view.getDesignResolutionSize();
    }

    /**
     * 相对于视图窗口，需要在X或Y方向缩放的最小比值
     */
    protected getScaleMin(size: cc.Size): number {
        const scale = this.getViewScale(size);
        return Math.min(scale.x, scale.y);
    }

    /**
     * 相对于视图窗口，需要在X或Y方向缩放的最大比值
     */
    protected getScaleMax(size: cc.Size): number {
        const scale = this.getViewScale(size);
        return Math.max(scale.x, scale.y);
    }

    // 获取相对于试图窗口的缩放
    protected getViewScale(size: cc.Size): { x: number, y: number } {
        const x = this.viewSize.width / (size.width || 1);
        const y = this.viewSize.height / (size.height || 1);
        return { x, y };
    }

    /**
     * 当前canvas尺寸与frame尺寸比例
     */
    protected get canvasScale(): number {
        if (CanvasExt.getAspectRatio() <= 1) {
            const canvasWidth = cc.view.getCanvasSize().width;
            const frameWidth = cc.view.getFrameSize().width;
            return canvasWidth / frameWidth;
        }
        else
            return 1;
    }

    /**
     * 直接设置节点scale值，忽略原始缩放
     */
    protected set scale(v: number) {
        this.node.setScale(v);
        DebugExt.debug("[UniformScaleBase] \n viewSize：", JSON.stringify(this.viewSize), " \n current scale: ", v);
    }

    /**
     * 相对原始节点缩放值叠加缩放
     */
    protected set scaleRelative(v: number) {
        const scale = this.originalScale * v;
        this.scale = scale;
    }

}
